package com.phei.netty.chat;

import java.util.concurrent.TimeUnit;

import com.phei.netty.chat4.HttpRequestHandler;

import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.DelimiterBasedFrameDecoder;
import io.netty.handler.codec.Delimiters;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.handler.stream.ChunkedWriteHandler;
import io.netty.handler.timeout.IdleStateHandler;
import io.netty.util.CharsetUtil;

public class WebSocketChannelInitializer extends ChannelInitializer<SocketChannel>{
	
    @Override
    protected void initChannel(SocketChannel ch) throws Exception {
		  ChannelPipeline pipeline = ch.pipeline();
	      
	      /**
	       * DelimiterBasedFrameDecoder: 基于分隔符的帧解码器。
	       * 两个参数的含义分别为：
	       *     1.帧数据的最大长度。
	       *  2.以XX作为分隔符, Delimiters.lineDelimiter()表示一\r\n或者\n作为分割符号。
	       *  例如一下字符串：
	       *  +--------------+
	       *  | ABC\nDEF\r\n |
	       *  +--------------+
	       *  解码后的字符串为:
	       *  +-----+-----+
	       *  | ABC | DEF |
	       *  +-----+-----+
	       *  而不是：
	       *  +----------+
	       *  | ABC\nDEF |
	       *  +----------+
	       */
		 
		  pipeline.addLast(new HttpServerCodec());
	      //ChunkedWriteHandler分块写处理，文件过大会将内存撑爆
	      pipeline.addLast(new ChunkedWriteHandler());
	      /**
	       * 作用是将一个Http的消息组装成一个完成的HttpRequest或者HttpResponse，那么具体的是什么
	       * 取决于是请求还是响应, 该Handler必须放在HttpServerCodec后的后面
	       */
	      pipeline.addLast(new HttpObjectAggregator(8192));
	      //pipeline.addLast(new HttpRequestHandler("/ws"));
	      //用于处理websocket, /ws为访问websocket时的uri
	      pipeline.addLast(new WebSocketServerProtocolHandler("/ws"));
	      /**
	      * IdleStateHandler: 空闲状态处理器。
	      * 四个参数：1.读空闲； 2.写空闲；3.读写空闲； 4.时间单位。
	      * 所谓的空闲是指多长时间没有发生过对应的时间，就触发调用.
	      */
	      pipeline.addLast(new IdleStateHandler(5, 5, 5, TimeUnit.SECONDS));
	      pipeline.addLast(new StateHandler());
	    /*  pipeline.addLast(new DelimiterBasedFrameDecoder(4096, Delimiters.lineDelimiter()));
	      pipeline.addLast(new StringDecoder(CharsetUtil.UTF_8));  //编码不指定，默认为utf-8
	      pipeline.addLast(new StringEncoder(CharsetUtil.UTF_8));*/
	      pipeline.addLast( new WebSocketHandler());
    }
}